// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: declaration of CVertex.
//   $Id$


// Vertex.h: interface for the CVertex class.
//
//////////////////////////////////////////////////////////////////////

#include "QName.h"
#include "DelayedDelete.h"
#if !defined(AFX_VERTEX_H__5624AB07_F96A_4814_81FD_BD0914599B80__INCLUDED_)
#define AFX_VERTEX_H__5624AB07_F96A_4814_81FD_BD0914599B80__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CIdResolver;
class CBoundNode;
class CImplModel;
class CVertex  
{
	friend class CVertexList;
public:
	HRESULT evaluate();
//	InstanceNode: a reference to the associated instance data node
	CBoundNode * m_pInstanceNode;
//	depList: a list of vertices that refer to this vertex
	CTypedPtrList<CPtrList,CVertex*> m_lDepList;
//	inDegree: the number of vertices on which this vertex depends
	long m_lInDegree;
//	visited: a flag used to ensure vertices are not added to a subgraph multiple times
	bool m_bVisited;
//	index: an association between vertices in the master dependency directed graph and a subgraph
	CVertex * m_pIndex;
//	type: indicates the aspect of the instance node represented by the vertex (the text content or a model item property such as readOnly or required)
	enum EType
	{
		Instance = 0,
		Calculate = 1,
		Constraint = 2,
		Readonly = 3,
		Relevant = 4,
		Required = 5
	}m_type;

	CVertex(CBoundNode * pInstanceNode, EType eType, CIdResolver * pResolver,CImplModel * pModel);

	virtual ~CVertex();
	//The XPath Expression that is evaluated to find
	//	the node (or value) at this vertex 
	CComBSTR m_sComputedExpression;
	
	void addDependent(CVertex * pVertex);

	CImplModel * m_pModel;

	//TODO : make private
	CIdResolver * m_pIdResolver;

public:
	// Called to add this vertex to the pertinent dependency subgraph of the appropriate model.
	HRESULT makePertinent(void);
};
struct IXmlState;
class CImplModel;
class CVertexList
	:public CDelayedDelete
{

public:
	void evaluate();
	//The public face of setVertex calls both private setVertex with
	//	the given appropriate parameters, to create a vertex between
	//	the given node and the property, and addVertex (type=value) 
	//	with the vertex returned from private setVertex.

	//TODO: this should probably return something (HRESULT?), but It is 
	//	only called by CImplBind::AddToGraph, and that does not seem
	//	to care.
	void setVertex
	(
		BSTR sXPath,
		IXMLDOMNode * pNode,
		CVertex::EType eType,
		CVertex * pDependentVertex,
		CIdResolver * pResolver,
		CImplModel * pModel
	);

	CVertexList():m_lVertexCount(0){};

	long m_lVertexCount;

	//Adds a new vertex to the dependency list.
	//	if this vertex has component vertices
	//	function arguments etc. it adds those too.
	
	HRESULT addVertex
	(
		CImplModel * pModel,
		IXMLDOMNode * pContext,
		CComBSTR sRef,
		bool bApplyFirstNodeRule,
		CVertex::EType eType,
		CVertex * vDependent,
		CTypedPtrArray<CPtrArray,CVertex*>  * pListToFill,
		CIdResolver * pResolver,
		bool bCreateIfNotFound
	);
	
	CVertex * createVertex(CBoundNode * pInstance, CVertex::EType eType,CIdResolver * pResolver,CImplModel * pModel);
	CVertex * findVertex(IXMLDOMNode * pInstanceNode, CVertex::EType eType);
	
	//Returns a class implementing the IXMLState interface.
	//	It should be thought of like an interface on this class,
	//	as it has access to the fundamental (private) data member:
	//	m_Nodemap.  For tidiness and ease of development,
	//	it exists in its own right.
	HRESULT GetXMLState(IXmlState ** ppState);

	// <summary>validates all the nodes pointed to in the list</summary>
	//<returns>S_OK if there were nodes to validate, otherwise S_FALSE</returns>
	HRESULT validate(void);
protected:
	virtual bool OnDeleteRequest();
private:
	virtual ~CVertexList();
	HRESULT FindDependees(BSTR sXPathExpression , CVertex * pvxDependent);
	void splitReference(CComBSTR sRef,CArray<CComBSTR,CComBSTR> * paRet);
	//may not need this, nodemap is better, need to check all uses though.
	CTypedPtrList<CPtrList,CVertex*> m_lVertices;
	void FlushVertexList();
	
//	CBoundNode * GetBoundNode(IXMLDOMNode * pXMLNode,IXMLDOMSchemaCollection * pSchemaCache);

	//This simply adds an individual vertex,
	//	called by addVertex. and by public setVertex
	HRESULT setVertex
	(
		IXMLDOMNode * pInstanceNode,
		CVertex::EType eType,
		CVertex * vDependent
		,CIdResolver * pResolver
		,CImplModel * m_pModel
		,CVertex ** ppvRetVal
	);
};

#include "boundnode.h"
#endif // !defined(AFX_VERTEX_H__5624AB07_F96A_4814_81FD_BD0914599B80__INCLUDED_)
